/**
 * 阿有 email:37798955@qq.com
 * 2017-11
 */
//fmt='yyyy-MM-dd hh:mm:ss'


//数组去重,仅适用于单个列值得数组
export function arrDistinct(arr) {
	var arr1 = []
	for (var i = 0; i < arr.length; i++) {
		var flag = true
		for (var j = 0; j < arr1.length; j++) {
			if (arr1[j] == arr[i]) {
				break;
				flag = false;
			}
		}
		if (flag)
			arr1.push(arr[i])
	}
	return arr1;
}
/**
 * 复制并排除
 * @param {*} obj 
 * @param {*} 排除项  如果缺少排除项 ,复制所有属性
 */
export function copyex(obj, 排除项) {
    let p = {}
    for (var key in obj) {　　//遍历对象的所有属性，包括原型链上的所有属性
        if (排除项 && 排除项.includes(key)) continue;
        p[key] = obj[key];
    }
    return p;
}
/**
 * 复制对象
 * @param {*} obj 
 * @param {*} 包含项 如果缺少包含项 ,无法复制任何属性
 */
export function copy(obj, 包含项) {
    let p = {}
    for (var key in obj) {　　//遍历对象的所有属性，包括原型链上的所有属性
        if (包含项 && 包含项.includes(key))
            p[key] = obj[key];
    }
    return p;
}
// var jj={
//     name:"dpi",
//     mmd:"2342",
//     xke:"12354",
//     xkcv:"1cx3"

// };
// console.log(copy(jj))
// console.log(copyex(jj))
// console.log(copy(jj,['mmd','name']))
// console.log(copyex(jj,['mmd','name']))

export function set2Jsonstr(set) {
    if (set == null || set.size == 0) return null;
    //return JSON.stringify(set) ;
    return JSON.stringify(Array.from(set));
}
export function jsonstr2Set(setstr) {
    if (setstr == null || setstr == "") return new Set();
    //return JSON.parse(setstr) ;
    return new Set(JSON.parse(setstr));
}

export function map2Jsonstr(map) {
    return JSON.stringify(mapToObj(map));

}
export function jsonstr2Map(str) {
    if (str==null||str=='')  return new Map();
    return ObjToMap(JSON.parse(str));
}

export function arrToMap(arr) {
    var map = new Map(arr.map(function (value, key) {
        return [key, value]
    }));
    return map
}
export function mapToObj(map) {
    var obj = {};
    for (let [key, value] of map) {
        obj[key] = value;
    }
    return obj;
}

export function ObjToMap(obj) {
    var map = new Map();
    for (let key in obj) {
        map.set(key, obj[key]);
    }
    return map;
}


/**
 * 建模工具对象，专门用于建模 
 * 模型定义 可以根据配置 mdconf 动态改变
 * 
 */
(function(e, t) {
	if ("object" == typeof exports && "object" == typeof module) module.exports._FD = new t();
	else if ("function" == typeof define && define.amd) define(t);
	else e._FD = new t(); //静态函数库
})(this, function() {
	/**
	 * types %%type1 替换项
	 * auto %%auto 替换项
	 * notnull %%notnull 替换项
	 * note %%note 替换项
	 */
	var mdconf = {
		types: function(lx) {
			return (lx.startWith('l') || lx.startWith('i')) ? "INTEGER" : (lx.startWith('dt') ? "NUMERIC" : "TEXT")
		},
		get: function(lx) {
			return (lx.startWith('l') || lx.startWith('i')) ? "getN" : "getV"
		},
		put: function(lx) {
			return (lx.startWith('l') || lx.startWith('i')) ? "putN" : "putV"
		},
		auto: {
			pt: "",
			zz: "", //primary key  AUTOINCREMENT
			sj: "",
			uu: ""
		},
		notnull: ["", "not null"],
		common: function(nt) {
			return _IS.isEmpty(nt) ? "" : ("comment '" + nt + "'");
		},
		title: function(zh) {
			return zh;
		}
	};
	this.config = function(obj) {
		Object.assign(mdconf, obj);
	};
	/**
	 * 根据表的字段模型mode 解析表table的字段集合
	 * @param {Object} table
	 * @param {Object} mode
	 * @param {Object} sp 分隔符
	 * @param {String} effcols 有效字段 {"字段1":[value,..],"字段1":[value,..]}
	 * @param {Object} isfilter  是否过滤模式 true 过滤模式时 以有效字段作为属性集输出，false 非过滤模式，输出所有字段
	 */
	function merge(table, mode, sp, effcols, isfilter) {
		if (table) {
			var tablename = table.tablename;
			var fds = table.fields; //alert(JSON.stringify(fds))
			if (_IS.isEmptyStr(effcols))
				effcols = undefined;
			else if (_IS.isString(effcols)) {
				effcols = JSON.parse(effcols);
			}
			var eachs = fds;
			if (isfilter) eachs = effcols;
			var s;

			var arr = [];
			for (var col in eachs) {
				if (!(col in fds)) continue;
				var zh = fds[col][0] || "";
				var lx = fds[col][1] || 't';
				var ky = fds[col][2] || "pt";
				var nnl = fds[col][3] || 0;
				var def = (effcols) ? effcols[col] : fds[col][4];
				var note = fds[col][5] || "";
				var s = mode.replaceAll("%%field0", col);
				s = s.replaceAll("%%title", mdconf.title(zh)); //中文标题
				s = s.replaceAll("%%note", mdconf.common(note)); //注释			
				s = s.replaceAll("%%auto", mdconf.auto[ky]);
				s = s.replaceAll("%%notnull", mdconf.notnull[nnl]);
				var d1, d2, d3;
				if (_IS.isEmptyStr(def)) {
					d1 = "null";
					d2 = "null";
					d3 = "null";
				} else {
					if (lx.startWith('l') || lx.startWith('i')) { //数值格式
						d1 = "default " + def;
						d2 = def;
						d3 = def;
					} else {
						d1 = "default \'" + def + "\'";
						d2 = "\"" + def + "\"";
						d3 = "'" + def + "'";
					}

				}
				s = s.replaceAll("%%type0", lx);
				s = s.replaceAll("%%type1", mdconf.types(lx));
				s = s.replaceAll("%%default", d1);
				s = s.replaceAll("%%value0", d3);
				s = s.replaceAll("%%value", d2);
				s = s.replaceAll("%%getV", mdconf.get(lx));
				s = s.replaceAll("%%putV", mdconf.put(lx));
				s = s.replaceAll("%%tbname", tablename); //表名
				arr.push(s);
			}
			if (sp) {
				s = arr.join(sp);
			} else {
				s = arr.join("");
			}
			return s;
		}
		return "";

	}


	/**
	 * 根据表的字段模型mode 解析表table的字段集合
	 * @param {Object} table
	 * @param {Object} mode
	 * @param {Object} sp 分隔符
	 * @param {String} effcols 有效字段 {"字段1":[value,..],"字段1":[value,..]}
	 */
	this.mergeFields = merge;
	/**
	 * 格式化数组，成新的字符串
	 * @param {Object} fields
	 * @param {Object} mode
	 * @param {Object} sp
	 */
	this.mergeArr = function(fields, mode, sp) {
		var arr = [];
		for (var i = 0; i < fields.length; i++) {
			arr.push(mode.replaceAll("$1", fields[0]))
		}
		if (sp) {
			s = arr.join(sp);
		} else {
			s = arr.join("");
		}
		return s;
	}
	this.mergeAnd = function(table, col, symbvalue) {
		var tablename = table.tablename;
		var fds = table.fields; //alert(JSON.stringify(fds))
		if (!(col in fds) || _IS.isEmpty(symbvalue)) return "";
		var lx = fds[col][1] || 't';
		var def = (symbvalue) ? symbvalue[1] : fds[col][4];
		var mode = "#1 #2 #4#3#5";
		var s = mode.replaceAll("#1", col);
		var m = "=",
			mbegin = "",
			mend = "";
		var n = symbvalue[0];
		if (n == '=' || n == '>' || n == '<' || n == '>=' || n == '<=' || n == 'not')
			m = n;
		else if (n.indexOf('%') > 0) {
			m = 'like';
			if (n.indexOf('%_') > 0)
				mbegin = "'%";
			if (n.indexOf('_%') > 0)
				mend = "%'";
		} else if (n.indexOf('in') > 0) {
			m = 'in';
			mbegin = "(";
			mend = ")";
		} else if (n.indexOf('exist') > 0) {
			m = 'exists';
			mbegin = "(";
			mend = ")";
		}
		s = s.replaceAll("#2", m); //运算符
		s = s.replaceAll("#4", mbegin); //开始边界
		s = s.replaceAll("#5", mend); //结束边界
		var d3, d5;
		if (_IS.isEmptyStr(def)) {
			d3 = "0";
			d5 = "null";
		} else {
			d3 = def;
			d5 = "'" + def + "'";
		}
		if (lx.startWith('l') || lx.startWith('i')) { //数值格式
			s = s.replaceAll("#3", d3);
		} else { //其他格式		
			s = s.replaceAll("#3", d5);
		}
		return s;
	}


});
// var arr = ['one', 'two', 'three'];
// console.log(arrToMap (arr));  
// var map = new Map();
// map.set(1, '111').set(2, '222').set(3, '333');
// console.log(mapToObj (map));
//
// var obj = {1: 'one', 2: 'two', 3: 'three'};
// console.log(ObjToMap (obj));
//

// var set=new Set();
// set.add(3);
// set.add([2,54]);
// set.add("asdfg");
// var s=set2Jsonstr(set);
// console.log(s)
// var set1=jsonstr2Set(s);
// console .log(set1)


//数组编织对象
//实现 对数组的排序,分组,左联接

export var _JO = (function () {
	this.concat = function (a, b) {
		a = a | [];
		for (var i = 0; i < b.length; i++) {
			a.push(b[i]);
		}
		return a;
	}
	//orderby="field1%a,field3,field4%,field2%d" 4种格式 分别表示升序,升序,升序,降序
	//模仿select order by 功能
	this.sort = function (arr, orderby) {
		if (!(arr instanceof Array)) return null;
		var sp = orderby.split(',')
		for (var i = sp.length - 1; i >= 0; i--) {
			var j = sp[i].indexOf('%');
			var field = null;
			var hz = null
			if (j > 0) {
				field = sp[i].slice(0, j);
				hz = sp[i].slice(j);
			} else {
				field = sp[i].slice(0)
			}
			if (j > 0 && (hz == '%d' || hz == '%D')) {
				arr = arr.sort(sortcompare(field, 'd')) //降序排列			
			} else {
				arr = arr.sort(sortcompare(field)) //升序排列
			}
		}
		return arr;
	}
	this.move = function (arr1, i, n) {
		var a = arr1[i]
		var j = i + n
		j = j < 0 ? 0 : j;
		if (arr1[i]) {
			arr1.splice(i, 1);
		}
		arr1.splice(j, 0, a);
		return arr1;
	}
	//私有函数 type==null||type==''||type=='a' 
	//升序排列 否则 =='d'倒叙排列
	function sortcompare(prop, type) {
		return function (obj1, obj2) {
			var val1 = obj1[prop];
			var val2 = obj2[prop];
			if (!isNaN(Number(val1)) && !isNaN(Number(val2))) {
				val1 = Number(val1);
				val2 = Number(val2);
			}
			var r = 0;
			if (val1 < val2) {
				r = -1;
			} else if (val1 > val2) {
				r = 1;
			}
			if (type == 'd') {
				return 0 - r;
			} else
				return r;
		}
	}

	//内联接 arr1 主表 ,arr2 子表, joins 连接字段 "字段1=字段1,字段2=字段2"
	//模仿select left join 功能
	this.innerjoin = function (arr1, arr2, joinstr) {
		var a = []
		var b = []
		var joins = joinstr.split(",")
		for (var k = 0; k < joins.length; k++) {
			var obj = joins[k].split('=')
			if (obj.length == 2) {
				a.push(obj[0])
				b.push(obj[1])
			}
		}
		var arr = [];
		for (var i = 0; i < arr1.length; i++) {
			var obj1 = arr1[i]
			for (var j = 0; j < arr2.length; j++) {
				var obj2 = arr2[j]
				var flag = 1;
				for (var k = 0; k < a.length; k++) {
					if (obj1[a[k]] != obj2[b[k]]) {
						flag = 0;
						break;
					}
				}
				if (flag == 1) {
					var obj = mergeObj(obj1, obj2)
					arr.push(obj)
				}
			}
		}
		return arr;
	}
	//如果两张表的字段相同必须提前select
	//左联接 arr1 主表 ,arr2 子表, joins 连接字段 "字段1=字段1,字段2=字段2"
	this.leftjoin = function (arr1, arr2, joinstr) {
		var a = []
		var b = []
		var joins = joinstr.split(",")
		//拆解 on 字段1=字段2,字段1=字段2,字段1=字段2
		for (var k = 0; k < joins.length; k++) {
			var obj = joins[k].split('=')
			if (obj.length == 2) {
				a.push(obj[0])
				b.push(obj[1])
			}
		}
		var arr = [];
		for (var i = 0; i < arr1.length; i++) {
			var obj1 = arr1[i]
			var neq = true; //假设不会匹配到,如果匹配到 =false
			for (var j = 0; j < arr2.length; j++) {
				var obj2 = arr2[j]
				var flag = 1;
				for (var k = 0; k < a.length; k++) { //所有条件都满足
					if (obj1[a[k]] != obj2[b[k]]) {
						flag = 0; //有一个条件不满足
						break;
					}
				}
				if (flag == 1) {
					var obj = mergeObj(obj1, obj2)
					arr.push(obj)
					neq = false
				}

			}
			if (neq)
				arr.push(obj1);
		}
		return arr;
	}
	//合并o1和o2 生成新的对象,可以只选择抽取o1和o2中的部分字段
	function mergeObj(o1, o2, o1fields, o2fields) {
		var fis = null;
		if (o1fields)
			fis = o1fields.split(',')
		var n1 = clone(o1, fis);
		if (o2fields == null) {
			for (var key in o2) {
				n1[key] = o2[key]
			}
		} else {
			var fis2 = o1fields.split(',')
			for (var key in fis2) {
				n1[key] = o2[key]
			}
		}
		return n1;
	}
	//arr 表示 待分组的数据
	//fields 表示去重的字段
	//根据fieldstr 对数组中的对象进行去重
	//模仿select distinct 功能
	this.distinct = function (arr, fieldstr) {
		var arr1 = []
		var fields = fieldstr.split(',')
		for (var i = 0; i < arr.length; i++) {
			var obj1 = arr[i]
			var flag1 = 1
			//console.log( arr1.length)
			for (var j = 0; j < arr1.length; j++) {
				var obj2 = arr1[j]
				if (equalprop(obj1, obj2, fields)) { //如果属性值相同
					flag1 = 0
					break;
				} else {
					continue;
				}
			}
			if (flag1 == 1)
				arr1.push(section(obj1, fields))
		}
		return arr1;
	}
	//根据属性截取对象的部分属性 生成新的对象
	function section(object, cols) {
		var n1 = {}
		var props = null
		if (cols == null || cols == '') return object;
		if (cols instanceof String)
			props = cols.split(',')
		else
			props = cols
		for (var i = 0; i < props.length; i++) {
			n1[props[i]] = object[props[i]]
		}
		return n1

	}
	//groupcols= group by 后面的字段
	//countcols="field1","field2"..，待统计的之短
	//模仿group by count 功能
	this.groupby = function (tarr, groupcols, countcols) {
		var arr = this.sort(tarr, groupcols) //先排序
		//		for(var i in arr) {
		//			console.log(JSON.stringify(arr[i]))
		//		}
		var arr1 = [] //
		var fields = groupcols.split(',')
		var cols = countcols.split(',') //统计字段
		var ob1 = null;
		for (var i = 0; i < arr.length; i++) {
			var obj1 = arr[i]
			var flag1 = 1 //分组标志
			//console.log( arr1.length)
			for (var j = 0; j < arr1.length; j++) {
				var obj2 = arr1[j]
				if (equalprop(obj1, obj2, fields)) {
					flag1 = 0 //维值相等 继续累加
					for (var k = 0; k < cols.length; k++) {
						var col = cols[k]
						ob1[col]["count"]++;
						ob1[col]["lst"] = obj1[col];
						ob1[col]["sum"] += obj1[col];
						if (ob1[col]["min"] > obj1[col])
							ob1[col]["min"] = obj1[col]
						else if (ob1[col]["max"] < obj1[col])
							ob1[col]["max"] = obj1[col];
					}
				}
			}
			if (flag1 == 1) { //维值不等 新建一条
				ob1 = section(obj1, fields) //截取部分字段
				//对每个字段进行基本统计
				for (var k = 0; k < cols.length; k++) {
					var col = cols[k]
					ob1[col] = {}
					ob1[col]["count"] = 1;
					ob1[col]["sum"] = obj1[col];
					ob1[col]["min"] = obj1[col];
					ob1[col]["max"] = obj1[col];
					ob1[col]["fst"] = obj1[col];
					ob1[col]["lst"] = obj1[col];
				}
				arr1.push(ob1)
			}
		}
		return arr1;
	}

	//对比两个对象的特定属性 判断是否相等
	function equalprop(obj1, obj2, fields) {
		//console.log(fields)
		var flag = 1
		for (var i = 0; i < fields.length; i++) {
			var field = fields[i]
			if (obj1[field] == obj2[field]) {
				continue;
			} else {
				flag = 0;
				break;
			}
		}
		if (flag == 0) {
			return false;
		} else
			return true;
	}
	//fields="field1 field11,field2 field12,field3 field13" 把field1转为field11属性 ,其他一样
	//实现select as 功能.并截取指定列名,无指定不显示
	this.select = function (arr, fields) {
		var arr1 = [];
		for (var i = 0; i < arr.length; i++) {
			var n1 = this.selectcols(arr[i], fields);
			arr1.push(n1)
		}
		//console.log("n1"+JSON.stringify(arr1));
		return arr1;
	}
	this.selectcols = function (rc, select) {
		//console.log("selectcols::"+select);
		if (select == null || select == '') return rc;
		var keys = select.split(',')
		var ar = [] //原字段数组
		var br = [] //新列名数组
		//分解老新列名
		for (var i = 0; i < keys.length; i++) {
			var astr = null;
			if (keys[i].indexOf(':') > -1)
				astr = keys[i].split(':');
			else if (keys[i].indexOf(' ') > -1)
				astr = keys[i].split(' ');
			else if (keys[i].indexOf(' as ') > -1)
				astr = keys[i].split(' as ');
			else
				astr = keys[i];

			if (astr == null) continue;
			if (_IS.isArray(astr)) {
				if (astr[0] in rc) {
					ar.push(astr[0]);
					br.push(astr[1]);
				}
			} else {
				if (astr in rc) {
					ar.push(astr);
					br.push(astr);
				}
			}

		}
		if (ar.length == 0) return;
		var n1 = {} //目标对象
		for (var j = 0; j < ar.length; j++) {
			n1[br[j]] = rc[ar[j]]
		}
		//console.log("n1"+JSON.stringify(n1));
		return n1;
	}

	this.getColList = function (arr, column, filter) {
		var arr1 = [] //目标数组
		if (arr.length == 0) return;
		if (column in arr[0]) {
			for (var i = 0; i < arr.length; i++) {
				var em = arr[i][column];
				if (filter) {
					em = filter(em)
				}
				arr1.push(em);
			}
		}
		return arr1;
	}

});
